package jinyilw.swing.visuals.Rcomp;

import jinyilw.common.file.FileTools;
import jinyilw.swing.SwingTools;
import jinyilw.swing.i18n.IString;

import javax.accessibility.AccessibleContext;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JRootPane;
import javax.swing.UIManager;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileSystemView;
import javax.swing.plaf.FileChooserUI;
import javax.swing.plaf.metal.MetalFileChooserUI;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.HeadlessException;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.ArrayList;

public class RFileChooser extends JFileChooser
{
	private static final long serialVersionUID = 7192265376201184004L;
	private static final int defaultWidth = 630;
	private static final int defaultHeight = 430;
	private static final IString fileString = new IString("file", "文件", "file");
	private static final IString existsMessage = new IString("existsMessage",
			"文件已存在，是否覆盖？", "The file already exists, whether to override?");
	private static final IString existsTitle = new IString("existsTitle", "文件已存在！",
			"The file already exists!");
	private String[] exts;
	private RDialog dialog;
	private String dialogTitle;
	private Component dialogSymbol;
	private Window ownerWindow;
	private final ArrayList<Window> visibleWindows = new ArrayList<>();
	private int returnValue = ERROR_OPTION;

	public RFileChooser()
	{
	}

	public RFileChooser(String path)
	{
		super(FileTools.getUserFile(path));
	}

	public RFileChooser(String path, String ext, String title)
	{
		this(FileTools.getUserFile(path), ext, title);
	}

	public RFileChooser(File file, String ext, String title)
	{
		super(file);
		if (ext != null)
		{
			exts = new String[1];
			exts[0] = ext;
			setAcceptAllFileFilterUsed(false);
			FileFilter filter = new FileNameExtensionFilter(
					ext + " " + fileString.getI18nString(), ext);
			addChoosableFileFilter(filter);
		}
		if (title != null)
			setDialogTitle(title);
	}

	public RFileChooser(String path, String[] exts, String title)
	{
		this(FileTools.getUserFile(path), exts, title);
	}

	public RFileChooser(File file, String[] exts, String title)
	{
		super(file);
		if (exts != null)
		{
			this.exts = exts;
			setAcceptAllFileFilterUsed(false);
			FileFilter[] fileFilters = new FileFilter[exts.length];
			for (int i = 0; i < exts.length; i++)
			{
				fileFilters[i] = new FileNameExtensionFilter(
						exts[i] + " " + fileString.getI18nString(), exts[i]);
				addChoosableFileFilter(fileFilters[i]);
			}
		}
		if (title != null)
			setDialogTitle(title);
	}

	public RFileChooser(File currentDirectory)
	{
		super(currentDirectory);
	}

	public RFileChooser(FileSystemView fsv)
	{
		super(fsv);
	}

	public RFileChooser(File currentDirectory, FileSystemView fsv)
	{
		super(currentDirectory, fsv);
	}

	public RFileChooser(String currentDirectoryPath, FileSystemView fsv)
	{
		super(currentDirectoryPath, fsv);
	}

	public String[] getExts()
	{
		return exts;
	}

	public File getOpenDirectory(Component com)
	{
		if (showOpenDialog(com) == JFileChooser.APPROVE_OPTION)
			return getSelectedFile();
		return null;
	}

	public File getSaveDirectory(Component com)
	{
		if (showSaveDialog(com) == JFileChooser.APPROVE_OPTION)
		{
			File file = getSelectedFile();
			setCurrentDirectory(file);
			return file;
		}
		return null;
	}

	public String getSaveDirectoryPath(Component com)
	{
		File directory = getSaveDirectory(com);
		if (directory != null)
			return directory.getAbsolutePath();
		return null;
	}

	public String openAndGetOpenFilePath(Component com)
	{
		File file = openAndGetOpenFile(com);
		if (file != null)
			return file.getAbsolutePath();
		return null;
	}

	public File openAndGetOpenFile(Component com)
	{
		setSelectedFile(null);
		FileChooserUI ui = getUI();
		if (ui instanceof MetalFileChooserUI)
			((MetalFileChooserUI) ui).setFileName("");
		if (showOpenDialog(com) == JFileChooser.APPROVE_OPTION)
			return getSelectedFile();
		return null;
	}

	public File[] openAndGetOpenFiles(Component com)
	{
		setSelectedFiles(null);
		FileChooserUI ui = getUI();
		if (ui instanceof MetalFileChooserUI)
			((MetalFileChooserUI) ui).setFileName("");
		if (showOpenDialog(com) == JFileChooser.APPROVE_OPTION)
			return getSelectedFiles();
		return null;
	}

	public String openAndGetSaveFilePath(Component com)
	{
		File file = openAndGetSaveFile(com);
		if (file != null)
			return file.getAbsolutePath();
		return null;
	}

	public File openAndGetSaveFile(Component com)
	{
		setSelectedFile(null);
		FileChooserUI ui = getUI();
		if (ui instanceof MetalFileChooserUI)
			((MetalFileChooserUI) ui).setFileName("");
		if (showSaveDialog(com) == JFileChooser.APPROVE_OPTION)
		{
			String ext = "";
			FileFilter[] fileFilters = getChoosableFileFilters();
			FileFilter filter = getFileFilter();
			for (int i = 0; i < fileFilters.length; i++)
				if (filter == fileFilters[i])
				{
					ext = exts[i];
					break;
				}
			String path = getSelectedFile().getAbsolutePath();
			if (!path.endsWith(ext))
				path = path + "." + ext;
			File file = new File(path);
			if (file.exists() && ROptionPane.showConfirmDialog(com,
					existsMessage, existsTitle) != 0)
				return null;
			if (file.exists())
				file.delete();
			return file;
		}
		return null;
	}

	public static boolean isOverride(File file, Component com)
	{
		if (file.exists() && ROptionPane.showConfirmDialog(com, existsMessage,
				existsTitle) != 0)
			return false;
		return true;
	}

	@Override
	public int showDialog(Component parent, String approveButtonText)
			throws HeadlessException
	{
		if (approveButtonText != null
				&& !approveButtonText.equals(getApproveButtonText()))
		{
			setApproveButtonText(approveButtonText);
			setDialogType(CUSTOM_DIALOG);
		}
		dialog = (RDialog) createDialog(parent);
		returnValue = ERROR_OPTION;
		rescanCurrentDirectory();
		dialog.setLocationRelativeTo(parent);
		visibleWindows.clear();
		if (ownerWindow != null)
			for (Window w : ownerWindow.getOwnedWindows())
				if (w.isVisible())
				{
					visibleWindows.add(w);
					w.setVisible(false);
				}
		dialog.setVisible(true);
		dialog.dispose();
		for (Window w : visibleWindows)
			w.setVisible(true);
		return returnValue;
	}

	@Override
	public void approveSelection()
	{
		returnValue = APPROVE_OPTION;
		if (dialog != null)
			dialog.setVisible(false);
		fireActionPerformed(APPROVE_SELECTION);
	}

	@Override
	public void cancelSelection()
	{
		returnValue = CANCEL_OPTION;
		if (dialog != null)
			dialog.setVisible(false);
		fireActionPerformed(CANCEL_SELECTION);
	}

	@Override
	public void setDialogTitle(String dialogTitle)
	{
		// String oldValue = this.dialogTitle;
		this.dialogTitle = dialogTitle;
		if (dialog != null)
		{
			dialog.setTitle(dialogTitle);
		}
		// firePropertyChange(DIALOG_TITLE_CHANGED_PROPERTY, oldValue,
		// dialogTitle);
	}

	public void setDialogSymbol(Component dialogSymbol)
	{
		this.dialogSymbol = dialogSymbol;
		if (dialog != null)
			dialog.setWindowSymbol(dialogSymbol);
	}

	@Override
	protected JDialog createDialog(Component parent) throws HeadlessException
	{
		if (dialog != null)
			return dialog;
		String title = dialogTitle != null
				? dialogTitle
				: getUI().getDialogTitle(this);
		putClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY,
				title);

		ownerWindow = SwingTools.getWindowForComponent(parent);
		dialog = new RDialog(ownerWindow, title, JDialog.DEFAULT_MODALITY_TYPE);
		dialog.setComponentOrientation(getComponentOrientation());
		dialog.addWindowListener(new WindowAdapter()
		{
			@Override
			public void windowClosing(WindowEvent e)
			{
				returnValue = CANCEL_OPTION;
			}
		});
		Container contentPane = dialog.getContentPane();
		contentPane.add(this, BorderLayout.CENTER);
		if (JDialog.isDefaultLookAndFeelDecorated()
				&& UIManager.getLookAndFeel().getSupportsWindowDecorations())
		{
			dialog.getRootPane()
					.setWindowDecorationStyle(JRootPane.FILE_CHOOSER_DIALOG);
		}
		if (dialogSymbol != null)
			dialog.setWindowSymbol(dialogSymbol);
		// dialog.setAlwaysOnTop(true);
		dialog.setSize(defaultWidth, defaultHeight);
		return dialog;
	}

	//	static Window getWindowForComponent(Component com)
	//	{
	//		if (com == null)
	//			return JOptionPane.getRootFrame();
	//		if (com instanceof Frame || com instanceof Dialog)
	//			return (Window) com;
	//		return getWindowForComponent(com.getParent());
	//	}
}
